/**
 * - 方法集
 */
const Util = {
	/**
	 * 获取指定偏移量月份的开始和结束时间戳
	 * @param {number} offset - 月份的偏移量，0 表示当前月份，1 表示上个月，以此类推
	 * @returns {Object} 包含指定月份开始和结束时间戳的对象
	 */
	getMonthTimestamp(offset) {
	  // 获取当前时间
	  const now = new Date();
	  // 获取当前年份和月份
	  const currentYear = now.getFullYear();
	  const currentMonth = now.getMonth() + 1;
	  // 获取指定偏移量后的年份和月份
	  const targetYear = currentYear;
	  const targetMonth = currentMonth - offset;
	  // 处理月份的借位
	  if (targetMonth <= 0) {
	    const yearOffset = Math.ceil(-targetMonth / 12); // 计算年份的借位偏移量
	    targetYear -= yearOffset; // 减去借位的年份偏移量
	    targetMonth += 12 * yearOffset; // 加上借位的月份偏移量
	  }
	  // 计算指定月份的开始和结束时间戳
	  const targetMonthStart = new Date(targetYear, targetMonth - 1, 1).getTime(); // 获取指定月份的开始时间戳
	  const targetMonthEnd = new Date(targetYear, targetMonth, 0).getTime() + 86400000 - 1; // 获取指定月份的结束时间戳，加上一天的毫秒数后再减去一毫秒
	
	  return {
	    monthStart: targetMonthStart,
	    monthEnd: targetMonthEnd
	  };
	},
	/**
	 * 根据给定的时间戳，计算未来的天数（整数）反编译
	 * @param {number} timestamp - 时间戳，单位为毫秒
	 * @returns {number} - 未来的天数
	 */
	getDaysAfter(timestamp) {
	  const now = new Date(); // 获取当前时间
	  const targetDate = new Date(timestamp); // 根据时间戳创建目标日期对象
	  const timeDiff = targetDate.getTime() - now.getTime(); // 计算目标日期和当前日期的时间差（毫秒）
	  const daysDiff = Math.ceil(timeDiff / (1000 * 60 * 60 * 24)); // 将时间差转换为天数并向上取整
	  return daysDiff;
	},
	/**
	 * 获取几天后几点的时间戳
	 * @param {number} days - 天数
	 * @param {number} hours - 小时数
	 * @returns {number} - 时间戳
	 */
	getTimestampAfter(days, hours) {
	    const now = new Date();
	    const targetDate = new Date(now.getTime() + (days * 24 * 60 * 60 * 1000));
	    targetDate.setHours(hours, 0, 0, 0);
	    return targetDate.getTime();
	},
	/**
	 * 使用正则表达式替换特殊字符
	 * @param str {string} 特殊字符转串
	 * @return {string}  普通字符串
*/
	escapeSpecialCharacters(str) {
	  return str.replace(/\\/g, "")
	             .replace(/\n/g, "")
	             .replace(/\r/g, "")
	             .replace(/\t/g, "")
	             .replace(/'/g, "")
	             .replace(/"/g, "");
	},
	/**
	 * 深拷贝
	 * @param obj 要被拷贝的对象
	 * @return {JSON} 深拷贝的对象
*/
	deepCopy(obj) {
	    if (obj === null || typeof obj !== 'object') {
	      return obj;
	    }
	    let temp = obj.constructor(); // 给出了正确的原型
	    for (let key in obj) {
	      if (obj.hasOwnProperty(key)) {
	        temp[key] = this.deepCopy(obj[key]); // 使用 this.deepCopy 进行递归调用
	      }
	    }
	    return temp;
	},
	/**
	 * 格式化数字，将大数字转换为带有单位的字符串
	 * @param {number} num - 需要格式化的整数
	 * @returns {string} - 格式化后的字符串
	 */
	formatNumber(num) {
	  if (num >= 1000 && num < 10000) {
	    return (num / 1000).toFixed(2) + 'k';
	  } else if (num >= 10000) {
	    return (num / 10000).toFixed(2) + 'w';
	  } else {
	    return num.toString();
	  }
	},

	/**
	 * 根据传入的属性对象或字符串，返回相应的属性字符串
	 * @param {Object|string} Attr - 属性对象或字符串
	 * @returns {string} - 返回拼接后的属性字符串
	 */
	isAttr(Attr) {
		if (typeof Attr == 'string') {
			return Attr;
		} else if (typeof Attr == 'object') {
			if (typeof Attr.attr == 'undefined') {
				// 如果属性对象中没有attr字段，将title字段拼接成字符串
				let result = '';
				result += Attr.map(item => {
					return item.title;
				}).join(', ');
				return result;
			} else {
				// 如果属性对象中有attr字段，将title字段和attr.title字段拼接成字符串
				let result = '';
				result += Attr.attr.map(item => {
					return item.title;
				}).join(', ');
				return Attr.title + (result ? '/' : '') + result;
			}
		} else {
			return '';
		}
	},
	/**
	 * 检索当前用户权限是否合格
	 * @param admin{array} 当前操作所需权限
	 * @return {boolean} 返回布尔值，有权限则为真其他为假
	 */
	userHasPermission(admin = ['']) {
		let role = uni.getStorageSync("uni-id-pages-userInfo").role

		let result = role.some(item => admin.includes(item))

		return result
	},
	/** 
	 * *验证 登录平台 
	 * @param platform 登录平台
	 * @param appname 软件名称
	 */
	isPlatform(platform, appname) {
		if (platform == 'web' && appname == '易派到家')
			return '公众号'
		else if (platform == 'app' && appname == '易派商家')
			return 'app'
		else if (platform == 'app' && appname == '易派到家')
			return 'app'
		else
			return '未知'
	},
	/**
	 * 将字符串缩短为50长度，超过50的部分用...省略
	 * @param {string} str - 要缩短的字符串
	 * @param {string} num - 截取长度
	 * @returns {string} - 缩短后的字符串
	 */
	shortenString(str,num) {
		if (str.length <= num) {
			return str; // 字符串长度小于等于50，直接返回原始字符串
		} else {
			return str.substring(0, num) + '...'; // 字符串长度大于50，截取前50个字符并加上省略号
		}
	},

	/**
	 * 格式化手机号，前三位加空格，中间四位加空格
	 * @param {string} phoneNumber - 手机号
	 * @returns {string} 格式化后的手机号
	 */
	formatPhoneNumber(phoneNumber) {
		if (!phoneNumber) {
			return ''; // 如果手机号为空，直接返回空字符串
		}
		// 去除空格和横杠
		phoneNumber = phoneNumber.replace(/\s/g, '').replace(/-/g, '');
		// 格式化手机号
		let formattedPhoneNumber = '';
		for (let i = 0; i < phoneNumber.length; i++) {
			if (i === 3 || i === 7) {
				formattedPhoneNumber += ' ';
			}
			formattedPhoneNumber += phoneNumber.charAt(i);
		}
		return formattedPhoneNumber;
	},
	/**
	 * 格式化银行卡卡号，每4位数后加一个空格
	 * @param {string} cardNumber - 银行卡卡号
	 * @returns {string} 格式化后的银行卡卡号
	 */
	formatBankCardNumber(cardNumber) {
		if (!cardNumber) {
			return ''; // 如果银行卡号为空，直接返回空字符串
		}
		// 去除空格和横杠
		cardNumber = cardNumber.replace(/\s/g, '').replace(/-/g, '');
		// 每4位数后加一个空格
		let formattedCardNumber = '';
		for (let i = 0; i < cardNumber.length; i++) {
			if (i > 0 && i % 4 === 0) {
				formattedCardNumber += ' ';
			}
			formattedCardNumber += cardNumber.charAt(i);
		}
		return formattedCardNumber;
	},
	/**
	 * - 将时间戳、拼接成年-月-日 时:分:秒格式字符串
	 * @param {Number} timestamp 时间戳 */
	formatTimestamp(timestamp) {
		const date = new Date(timestamp);
		// 获取年、月、日、时、分、秒
		const year = date.getFullYear();
		const month = String(date.getMonth() + 1).padStart(2, '0');
		const day = String(date.getDate()).padStart(2, '0');
		const hours = String(date.getHours()).padStart(2, '0');
		const minutes = String(date.getMinutes()).padStart(2, '0');
		const seconds = String(date.getSeconds()).padStart(2, '0');
		// 拼接成年-月-日 时:分:秒格式字符串
		const formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
		return formattedTime;
	},

	/*** - 将时间戳、转换成 时分 格式字符串
	 * @param {Number} timestamp 时间戳 */
	ConversionTimeDivision(timestamp) {
		const date = new Date(timestamp);
		// 获取 时、分
		const hours = String(date.getHours()).padStart(2, '0');
		const minutes = String(date.getMinutes()).padStart(2, '0');
		// 拼接成年-月-日 时:分:秒格式字符串
		const formattedTime = `${hours}${minutes}`;
		return formattedTime;
	},
	/**
	 * - 隐藏手机号中间的四位数字
	 * @param {Number}phoneNumber 手机号
	 */
	hidePhoneNumber(phoneNumber) {
		if (phoneNumber.length === 11) {
			const hiddenPart = phoneNumber.slice(3, 7).replace(/\d/g, '*');
			return phoneNumber.slice(0, 3) + hiddenPart + phoneNumber.slice(7);
		}
		return phoneNumber;
	},
	/**
	 * 方法：在字符串的特定位置添加冒号
	 * @param {Number} str 字符串
	 * @returns {String} 返回加上冒号的字符串 */
	addColon(str) {
		// 检查字符串的长度是否为 4
		if (str.length == 4) {
			// 使用 slice() 方法将字符串分成两部分，并在中间插入冒号
			const formattedStr = str.slice(0, 2) + ":" + str.slice(2);
			return formattedStr;
		} else {
			return str; // 如果长度不为 4，则返回原始字符串
		}
	},
	/**
	 * 方法：移除字符串中的冒号
	 * @param {String} phoneNumber 字符串
	 * @returns {String} 返回移除冒号后的字符串 */
	removeColon(phoneNumber) {
		const withoutColon = phoneNumber.replace(":", "");
		// return parseInt(withoutColon, 10); //返回移除冒号后的整数
		return withoutColon;
	},

	/**
	 * 获取当天开始的时间戳和当天结束的时间戳
	 * @param {number} offset 偏移量，表示从当天向前或向后的天数
	 * @returns {object} 包含开始时间戳和结束时间戳的对象
	 */
	getDayTimestamps(offset) {
		const currentDate = new Date();
		const targetDate = new Date(currentDate);
		// 根据偏移量计算目标日期
		targetDate.setDate(currentDate.getDate() - offset);
		// 设置目标日期的时间为凌晨 00:00:00.000
		targetDate.setHours(0, 0, 0, 0);
		const startTime = targetDate.getTime();
		// 设置目标日期的时间为当天的最后一刻 23:59:59.999
		targetDate.setHours(23, 59, 59, 999);
		const endTime = targetDate.getTime();
		return {
			startTime,
			endTime
		};
	},
	/**
	 * 获取指定日期的时间戳范围（零点和最后一刻）
	 * @param {string} dateStr - 日期字符串，格式可以是任何可被 Date 构造函数解析的格式
	 * @returns {Object} - 包含零点时间戳和最后一刻时间戳的对象
	 */
	getTimestampRange(dateStr) {
		const date = new Date(dateStr); // 根据日期字符串创建 Date 对象
		const startTimestamp = date.setHours(0, 0, 0, 0); // 将时、分、秒和毫秒设置为零，获取零点时间戳
		const endTimestamp = date.setHours(23, 59, 59, 999); // 将时、分、秒和毫秒设置为最后一刻，获取最后一刻时间戳

		return {
			start: startTimestamp,
			end: endTimestamp
		}; // 返回包含零点时间戳和最后一刻时间戳的对象
	},

	/**
	 * *获取指定*天前开始时间戳和当前结束时间戳
	 * @param time 表示**天前的日期和时间
	 * @returns {Object} - 返回包含*天前开始时间戳和当前结束时间戳的对象 
	 */
	getStartAndEndTimestamp(time) {
		const date = new Date(); // 创建一个新的Date对象，表示当前日期和时间 
		const sevenDaysAgo = new Date(new Date().getTime() - time * 24 * 60 * 60 * 1000); // 创建一个新的Date对象，表示七天前的日期和时间
		const startTime = sevenDaysAgo.setHours(0, 0, 0, 0); // 将七天前的日期设置为零点，返回开始时间戳 
		const endTime = date.setHours(23, 59, 59, 999); // 将当前日期设置为当天的最后一刻，返回结束时间戳
		return {
			startTime: startTime,
			endTime: endTime
		}; // 返回一个包含开始时间戳和结束时间戳的对象
	},

	/**
	 * 获取指定日期的零点或最后一刻时间戳
	 * @param {string} dateStr - 日期字符串，格式可以是任何可被 Date 构造函数解析的格式
	 * @param {number} type - 类型：0 表示获取零点时间戳，1 表示获取最后一刻时间戳
	 * @returns {number} - 返回指定日期的最后一刻或零点时间戳
	 */
	getTimesTamp(dateStr, type) {
		const date = new Date(dateStr); // 根据日期字符串创建 Date 对象
		if (type === 0) {
			// 获取零点时间戳
			return date.setHours(0, 0, 0, 0);
		} else if (type === 1) {
			// 获取最后一刻时间戳
			return date.setHours(23, 59, 59, 999);
		} else {
			// 若传入的 type 不是 0 或 1，则返回当前时间的时间戳
			return new Date().getTime();
		}
	},
	/**
	 * 将 "yyyy MM" 格式的字符串转换为当月开始时间戳和当月结束时间戳
	 * @param {string} dateString - 日期字符串，格式为 "yyyy MM"，例如 "2023 09"
	 * @returns {Object} - 包含当月开始时间戳和当月结束时间戳的对象 */
	convertToTimestamps(dateString) {
		const [year, month] = dateString.split(' '); // 将日期字符串拆分为年份和月份
		const startDate = new Date(`${year}-${month}-01`); // 构建当月的第一天日期对象
		const endDate = new Date(startDate.getFullYear(), startDate.getMonth() + 1, 0); // 构建当月的最后一天日期对象
		const startTime = startDate.setHours(0, 0, 0, 0); // 获取当月开始时间戳（当月第一天的零点）
		const endTime = endDate.setHours(23, 59, 59, 999); // 获取当月结束时间戳（当月最后一天的最后一刻）
		return {
			startTime,
			endTime
		};
	},
	/**
	 * 隐藏手机号码中间的部分数字
	 * @param {string} phoneNumber - 需要隐藏的手机号码
	 * @returns {string} - 隐藏中间部分数字后的手机号码
	 */
	hidePhoneNumber(phoneNumber) {
		if (phoneNumber.length === 11) {
			const hiddenPart = phoneNumber.slice(3, 7).replace(/\d/g, "*");
			return phoneNumber.slice(0, 3) + hiddenPart + phoneNumber.slice(7);
		}
		return phoneNumber;
	},
	/**
	 * 生成订单号函数
	 * 使用当前日期和随机数生成唯一的订单号
	 * @returns {string} 订单号
	 */
	setOutTradeNo(letter) {
		const date = new Date(); // 当前日期
		const outTradeNo = letter + date.getFullYear() + '' + (date.getMonth() + 1) + '' + date.getDate() + '' +
			date.getHours() + '' + date.getMinutes() + '' + date.getSeconds(); // 根据当前日期生成订单号的前缀部分
		const random = Math.round(Math.random() * 100) + '' + Math.round(Math.random() * 100) + '' + Math.round(
			Math.random() * 100); // 生成随机数部分
		return outTradeNo + '' + random; // 返回完整的订单号
	},
	/**
	 * 获取最近N天的日期
	 * @param Num type{number} 最近多少天
	 * @returns {Array} 最近N天的日期数组，日期格式为 "mm/dd"
	 */
	getRecentThirtyDays(Num) {
		var dates = [];
		var today = new Date();
		for (var i = 0; i < Num; i++) {
			var date = new Date(today);
			date.setDate(today.getDate() - i);
			dates.push(this.formatDate(date));
		}
		return dates;
	},

	/**
	 * 格式化日期为 "yyyy-mm-dd" 的形式
	 * @param {Date} date - 要格式化的日期对象
	 * @returns {string} 格式化后的日期字符串
	 */
	formatDate(date) {
		var year = date.getFullYear();
		var month = date.getMonth() + 1;
		var day = date.getDate();

		// 格式化日期为 "yyyy-mm-dd" 的形式
		return (month < 10 ? '0' + month : month) + '/' + (day < 10 ? '0' + day : day);
	},
	/**
	 * 计算整数数组的平均值
	 * 
	 * @param {number[]} numbers - 整数数组
	 * @returns {number} - 平均值
	 */
	calculateAverage(numbers) {
		let sum = 0;
		for (let i = 0; i < numbers.length; i++) {
			sum += numbers[i];
		}
		return sum / numbers.length;
	},

	/**
	 * 	根据订单状态改变字体颜色
	 *@param {Number} Num 整数1、2、3····  */
	onStatus(Num) {
		switch (Num) {
			case 0:
				return "#73629d"
				break;
			case 1:
				return "#e17055"
				break;
			case 2:
				return "#E45552"
				break;
			case 3:
				return "#ffd500"
				break;
			case 4:
				return "#f1c40f"
				break;
			case 5:
				return "#7de68f"
				break;
			case 6:
				return "#00da74"
				break;
			case 7:
				return "#999"
				break;
			case 8:
				return "#999"
				break;
			case 9:
				return "#999"
				break;
			default:
				return "#999"
				break;
		}
	},
	/**
	 * 封装方法，计算两个值之间的百分比
	 *
	 * @param {number} value1 - 第一个值
	 * @param {number} value2 - 第二个值
	 * @returns {string} - 百分比字符串整数
	 */
	calculatePercentage(value1, value2) {
		let percentage = (value1 / (value1 + value2)) * 100; // 计算百分比

		// 确保百分比在 0 到 100 之间
		percentage = Math.min(100, Math.max(0, percentage));

		return percentage.toFixed(2); // 返回百分比字符串整数
	}
};

export default Util;